package com.ec.bl.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ec.bl.domain.dto.BillQueryDTO;
import com.ec.api.domain.po.Bill;
import com.ec.api.domain.po.BillDetail;
import com.ec.bl.domain.vo.BillDetailVO;
import com.ec.bl.domain.vo.BillQueryVO;
import com.ec.bl.domain.vo.BillWithDetailsVO;
import com.ec.bl.mapper.BillDetailMapper;
import com.ec.bl.mapper.BillMapper;

import com.ec.bl.service.BillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements BillService {
    @Autowired
    private  BillMapper billMapper;
    @Autowired
    private BillDetailMapper billDetailMapper;

    // BillServiceImpl.java 中的缓存实现
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String BILL_CACHE_KEY = "bill:details:";
    private static final String BILL_PAGE_CACHE_KEY = "bill:page:";
    private static final int CACHE_EXPIRE_SECONDS = 300; // 5分钟

    @Override
    public IPage<BillQueryVO> queryBillPage(BillQueryDTO queryDTO) {
        // 构建缓存key
        String cacheKey = BILL_PAGE_CACHE_KEY + queryDTO.getCurrent() + ":" + queryDTO.getSize() + ":" +
                (queryDTO.getElderlyUserId() != null ? queryDTO.getElderlyUserId() : "all") + ":" +
                (queryDTO.getStatus() != null ? queryDTO.getStatus() : "all");

        // 从缓存中获取
        String cachedResult = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null && !cachedResult.isEmpty()) {
            try {
                // 使用具体的Page类型进行反序列化
                Page<BillQueryVO> result = JSON.parseObject(cachedResult, new TypeReference<Page<BillQueryVO>>() {});
                return result;
            } catch (Exception e) {
                // 缓存数据异常，删除缓存
                stringRedisTemplate.delete(cacheKey);
            }
        }

        // 从数据库查询
        Page<BillQueryVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<BillQueryVO> result = baseMapper.selectBillPage(page, queryDTO);

        // 存入缓存 - 确保对象不为null再缓存
        if (result != null) {
            try {
                stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
            } catch (Exception e) {

            }
        }

        return result;
    }

    @Override
    public BillWithDetailsVO getBillWithDetails(Long billId) {
        String cacheKey = BILL_CACHE_KEY + billId;

        // 从缓存中获取
        String cachedBill = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedBill != null && !cachedBill.isEmpty()) {
            try {
                BillWithDetailsVO billVO = JSON.parseObject(cachedBill, BillWithDetailsVO.class);
                if (billVO != null) {
                    return billVO;
                }
            } catch (Exception e) {
                // 缓存数据异常，删除缓存
                stringRedisTemplate.delete(cacheKey);
            }
        }

        // 从数据库查询
        BillWithDetailsVO billVO = billMapper.selectBillWithElderlyInfo(billId);
        if (billVO == null) {
            return null;
        }

        List<BillDetailVO> details = billDetailMapper.selectDetailsByBillId(billId);
        details.forEach(detail -> {
            detail.setItemTypeDesc(getItemTypeDesc(detail.getItemType()));
        });

        billVO.setDetails(details);
        billVO.setStatusDesc(getStatusDesc(billVO.getStatus()));

        // 存入缓存
        try {
            stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(billVO), CACHE_EXPIRE_SECONDS, TimeUnit.SECONDS);
        } catch (Exception e) {
        }

        return billVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> createBill(Bill bill, List<BillDetail> billDetails) {
        // 1. 校验账单总额
        if (bill.getTotalAmount().signum() < 0) {
            return Result.error("账单总额不能为负");
        }

        // 2. 保存账单
        billMapper.insert(bill);

        // 3. 设置账单ID到详情并保存
        for (BillDetail detail : billDetails) {
            if (detail.getAmount() == null || detail.getItemType() == null || detail.getItemDescription() == null) {
                throw new IllegalArgumentException("账单详情字段缺失");
            }
            detail.setBillId(bill.getId());
            billDetailMapper.insert(detail);
        }

        return Result.ok(bill.getId());
    }

    // 清除账单相关缓存
    private void clearBillCache(Long billId) {
        // 清除单个账单缓存
        stringRedisTemplate.delete(BILL_CACHE_KEY + billId);

        // 清除分页缓存（使用模糊匹配）
        Set<String> keys = stringRedisTemplate.keys(BILL_PAGE_CACHE_KEY + "*");
        if (keys != null && !keys.isEmpty()) {
            stringRedisTemplate.delete(keys);
        }
    }


    /**
     * 获取费用类型描述
     */
    private String getItemTypeDesc(String itemType) {
        switch (itemType) {
            case "accommodation":
                return "住宿费";
            case "medication":
                return "药品费";
            case "other":
                return "其他费用";
            default:
                return "未知费用";
        }
    }

    /**
     * 获取状态描述
     */
    private String getStatusDesc(String status) {
        switch (status) {
            case "unpaid":
                return "未支付";
            case "paid":
                return "已支付";
            case "overdue":
                return "逾期";
            default:
                return "未知状态";
        }
    }
}
